package br.com.abril.booking;

import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import br.com.abril.booking.transformer.BookingMaintenanceTransformer;
import br.com.abril.prevision.ExecutivePrevision;
import br.com.abril.prevision.PrevisionService;
import br.com.abril.wallet.BookingWallet;

import com.force.abril.api.maintanence.client.BookingMaintenanceClientService;
import com.force.abril.api.maintanence.client.request.MaintenanceEntry;
import com.topi.event.EventMonitorRepository;

@Component
public class BookingLoader {
	
	private static final Logger logger = Logger.getLogger(BookingLoader.class);

	@Autowired
	private BookingService bookingService;

	@Autowired
	private PrevisionService previsonService;

	@Autowired
	private BookingMaintenanceTransformer transformer;

	@Autowired
	private BookingMaintenanceClientService service;

	@Transactional(readOnly = true)
	public Page<BookingWallet> getWalletByPage(Integer nextPage) {
		Pageable pageable = new PageRequest(nextPage, BookingWallet.PAGE_SIZE);
		return bookingService.getAllWallets().findAll(pageable);
	}

	public void processWallets(List<BookingWallet> wallets) {

		for (BookingWallet bookingWallet : wallets) {

			List<ExecutiveBooking> bookingExecutives = bookingService
					.findExecutivesByWallet(bookingWallet.getWallet());

			List<ExecutivePrevision> previsionExecutives = bookingService
					.findExecutivesforPrevisionByWallet(bookingWallet
							.getWallet());
			
			if (previsionExecutives.isEmpty() && bookingExecutives.isEmpty()) continue;

			
			if (previsionExecutives.isEmpty() && !bookingExecutives.isEmpty()) {
				processExecutives(  bookingExecutives);
				continue;
			}
			
			
			
			if (bookingService.executiveBookingTeamIsEqualsPrevision(
					bookingExecutives, previsionExecutives)) {
				processExecutives(bookingExecutives);
				continue;
			}

			// team is not equals then sort all teams by reservation date.

			// Join Teams
			if (!bookingService.previsionTeamIsAfterThanBooking(
					previsionExecutives, bookingExecutives)) {
				processExecutives(bookingExecutives);
				continue;
			}

			processExecutivesFromPrevision(previsionExecutives);

		}

	}

	@Transactional
	public void processExecutives(List<ExecutiveBooking> executives) {
		if (executives.isEmpty()) return;
		
		List<ExecutiveBooking> lastExecutives = bookingService
														.filterTeamByLastBooking(executives.get(0).getReserva__c()
																				, executives);
		
		MaintenanceEntry request = transformer.toMaintenance(lastExecutives);
		
		try{
			
			service.create(request);
			
		} catch (Exception e) {
			logger.error(e.getLocalizedMessage(), e);
			bookingService.updateExecutiveBookingsWithError(lastExecutives, e);
		}
	}

	@Transactional
	public void processExecutivesFromPrevision(List<ExecutivePrevision> executives) {

		
		List<ExecutivePrevision> lastExecutives = bookingService
														.filterTeamByLastPrevison(executives.get(0).getPrevisao__c()
																				, executives);
		
		MaintenanceEntry request = transformer.toMaintenancePrevision(lastExecutives);
		
		
		try{
			
			service.create(request);
			
		} catch (Exception e) {
			previsonService.updateExecutivePrevisionsWithError(lastExecutives, e);
		}
	
	
	}

	public void load() {

		// Determinar o tamanho da lista
		int page = 0;
		int totalOfPages = 1;

		while (page <= totalOfPages) {

			Page<BookingWallet> walletPage = getWalletByPage(page);

			if (page == 0) {
				totalOfPages = walletPage.getTotalPages();
			}

			if (walletPage != null && walletPage.getContent() != null) {
				processWallets(walletPage.getContent());
			} 

			page++;

		}

		//

	}

}
